#include "xbeestruct.h"
udata_unit8 GetXbeeMessageType(std::vector<unsigned char> input_string)
{
	if(input_string[0]==0x7E)
	return input_string[3];//0->2 start delim+length
	else return ( const udata_unit8) XBEE_STRUCTURE_NOT_FOUND;
}
std::vector<unsigned char> XBeeTrReq::Sendstr()
{
	unsigned int writable_length=data_length+14;// 14 - content size
	std::vector<unsigned char> output(writable_length+4);
	//general info
	output[0]=XBEE_PACKET_STARTBYTE;
	output[1]=(writable_length >> 8) & 0xFF;//length msb
	output[2]=writable_length & 0xFF;//length lsb
	output[3]=frame_type;
	output[4]=frame_ID;
	//dest adress
	for( size_t i=0;i<8;i++)
		output[5+i]=dest_adress64[i];
	for( size_t i=0;i<2;i++)
		output[13+i]=dest_adress16[i];

	output[15]=broadcast_radius;
	output[16]=Options;
	//data itself
	for( size_t i=0;i<data_length;i++)
		output[17+i]=TrReq_data[i];
	//get checksumm
	udata_unit8 chksumm=0;
	for( size_t i=0;i<writable_length;i++)
		chksumm+=output[3+i];
	output[writable_length+3]=255-chksumm;
	return output;
}
bool XBeeTrReq::ReadString(std::vector<unsigned char> inp_string)
{
	if(inp_string[0]!=XBEE_PACKET_STARTBYTE)
		return false;
	if((unsigned char)inp_string[3]!=(unsigned char)frame_type)
		return false;
	//TODO check checksum?
	//read length
	this->data_length=-14+(inp_string[1]<<8)+inp_string[2];// data=frame-frame_spec+ msb[1]+lsb[0]
	
	int testgg=inp_string.size();
	if(inp_string.size()<data_length+14+4)
		return false;
	//read frame data
	frame_ID=inp_string[4];
	for( size_t i=0;i<8;i++)
		dest_adress64[i]=inp_string[5+i];
	for( size_t i=0;i<2;i++)
		dest_adress16[i]=inp_string[13+i];
	//15 - broadcast is default by now
	Options=inp_string[16];
	//read data
	for( size_t i=0;i<data_length;i++)
		TrReq_data[i]=inp_string[17+i];
	//TODO check for max size
	return true;
}

bool FromHexString(QString in_string, QString & out_string)
{

	size_t sizein=in_string.size();
	if(sizein%2!=0)
		return false; //not n/2 input
	out_string.resize(0);
	bool ok=true;
	for(size_t i=0;i< sizein/2;i++)
	{
		QChar ggg=QChar(in_string.mid(i*2,2).toInt(&ok,16));
		out_string.push_back(QChar(in_string.mid(i*2,2).toInt(&ok,16)));

	}
	return true;

}
bool FromHexString(QString in_string, char * out_string, int out_size)
{
	size_t sizein=in_string.size();
	if(sizein%2!=0)
		return false; //not n/2 input
	if(out_size<(int) sizein/2)
		return false;
	//out_string.resize(0);
	bool ok=true;
	for(size_t i=0;i< sizein/2;i++)
	{
		QChar ggg=QChar(in_string.mid(i*2,2).toInt(&ok,16));
		//out_string.push_back(QChar(in_string.mid(i*2,2).toInt(&ok,16)));
		out_string[i]=in_string.mid(i*2,2).toInt(&ok,16);

	}
	return true;

}
QString FromCharToHex(std::vector<unsigned char> in_string)
{
	QString out_string((const char*)0);
	for( size_t i=0;i<in_string.size();i++)
	{
		QByteArray tmparr=QByteArray::number((int)in_string[i],16);
		out_string.append(tmparr);
	}
	return out_string;
}
QString FromCharToHex(QString in_string)
{
	QString out_string((const char*)0);
	for( size_t i=0;i<(size_t)in_string.size();i++)
	{
		QByteArray tmparr=QByteArray::number((int)(in_string[i].toAscii()),16);
		out_string.append(tmparr);
	}
	return out_string;
}
QString FromCharToHex(QByteArray in_string)
{
	QString out_string((const char*)0);
	for( size_t i=0;i<(size_t)in_string.size();i++)
	{
		QByteArray tmparr=QByteArray::number((int)(in_string[i]),16);
		out_string.append(tmparr);
	}
	return out_string;
}
QString FromCharToHex(char* in_string,int in_size,bool is_spacing_needed)
{
	QString out_string((const char*)0);
	for( size_t i=0;i<(size_t)in_size;i++)
	{
		QByteArray tmparr=QByteArray::number((unsigned char)in_string[i],16).toUpper();
		if(tmparr.size()==1)
			tmparr.push_back('0');
		if(is_spacing_needed)
			tmparr.push_back(' ');
		out_string.append(tmparr);
	}
	return out_string;
}
std::vector<unsigned char> XBeeRecievePacket::Sendstr()
{
	unsigned int writable_length=data_length+12;// 14 - content size
	std::vector<unsigned char> output(writable_length+4);
	//general info
	output[0]=XBEE_PACKET_STARTBYTE;
	output[1]=(writable_length >> 8) & 0xFF;//length msb
	output[2]=writable_length & 0xFF;//length lsb
	output[3]=frame_type;
	//dest adress
	for( size_t i=0;i<8;i++)
		output[4+i]=dest_adress64[i];
	for( size_t i=0;i<2;i++)
		output[12+i]=dest_adress16[i];

	output[14]=Options;
	//data itself
	for( size_t i=0;i<data_length;i++)
		output[15+i]=TrReq_data[i];
	//get checksumm
	udata_unit8 chksumm=0;
	for( size_t i=0;i<writable_length;i++)
		chksumm+=output[3+i];
	output[writable_length+3]=255-chksumm;
	return output;
}
bool XBeeRecievePacket::ReadString(std::vector<unsigned char> inp_string)
{
	if(inp_string[0]!=XBEE_PACKET_STARTBYTE)
		return false;
	if((unsigned char)inp_string[3]!=(unsigned char)frame_type)
		return false;
	if(inp_string.size()<4)
		return false;
	//if(inp_string.size()<25)
	//	int gggh=0;
	//TODO check checksum?
	//read length
	this->data_length=-12+(inp_string[1]<<8)+inp_string[2];// data=frame-frame_spec+ msb[1]+lsb[0]
	int testgg=inp_string.size();
	if(inp_string.size()<data_length+12+4)
		return false;
	//read frame data;
	for( size_t i=0;i<8;i++)
		dest_adress64[i]=inp_string[4+i];
	for( size_t i=0;i<2;i++)
		dest_adress16[i]=inp_string[12+i];
	Options=inp_string[14];
	//read data
	for( size_t i=0;i<data_length;i++)
		TrReq_data[i]=inp_string[15+i];
	//TODO check for max size
	return true;
}

std::vector<unsigned char> ATCommand::Sendstr()
{
	unsigned int writable_length=4;// 14 - content size
	std::vector<unsigned char> output(writable_length+4);
	//general info
	output[0]=XBEE_PACKET_STARTBYTE;
	output[1]=(writable_length >> 8) & 0xFF;//length msb
	output[2]=writable_length & 0xFF;//length lsb
	output[3]=frame_type;
	output[4]=frame_ID;
	for( size_t i=0;i<2;i++)
		output[5+i]=AT_Command[i];
	//get checksumm
	udata_unit8 chksumm=0;
	for( size_t i=0;i<writable_length;i++)
		chksumm+=output[3+i];
	output[writable_length+3]=255-chksumm;
	return output;
}

bool ATCommand::ReadString(std::vector<unsigned char> inp_string)
{
	if(inp_string[0]!=XBEE_PACKET_STARTBYTE)
		return false;
	if((unsigned char)inp_string[3]!=(unsigned char)frame_type)
		return false;
	//TODO check checksum?
	if(inp_string.size()<6)
		return false;
	//read frame data;
	frame_ID=inp_string[4];
	for( size_t i=0;i<2;i++)
		AT_Command[i]=inp_string[5+i];
	//TODO check for max size
	return true;
}

std::vector<unsigned char> ATCommandResp::Sendstr()
{
	unsigned int writable_length=data_length+5;// 14 - content size
	std::vector<unsigned char> output(writable_length+4);
	//general info
	output[0]=XBEE_PACKET_STARTBYTE;
	output[1]=(writable_length >> 8) & 0xFF;//length msb
	output[2]=writable_length & 0xFF;//length lsb
	output[3]=frame_type;
	output[4]=frame_ID;
	for( size_t i=0;i<2;i++)
		output[5+i]=AT_Command[i];
	output[7]=Command_status;
	//data itself
	for( size_t i=0;i<data_length;i++)
		output[8+i]=AtCommResp_data[i];
	//get checksumm
	udata_unit8 chksumm=0;
	for( size_t i=0;i<writable_length;i++)
		chksumm+=output[3+i];
	output[writable_length+3]=255-chksumm;
	return output;
}
bool ATCommandResp::ReadString(std::vector<unsigned char> inp_string)
{
	if(inp_string[0]!=XBEE_PACKET_STARTBYTE)
		return false;
	if((unsigned char)inp_string[3]!=(unsigned char)frame_type)
		return false;
	//TODO check checksum?
	//read length
	this->data_length=-5+(inp_string[1]<<8)+inp_string[2];// data=frame-frame_spec+ msb[1]+lsb[0]
	int testgg=inp_string.size();
	if(inp_string.size()<data_length+5+4)
		return false;
	//read frame
	frame_ID=inp_string[4];
	for( size_t i=0;i<2;i++)
		AT_Command[i]=inp_string[5+i];
	Command_status=inp_string[7];
	//read data
	for( size_t i=0;i<data_length;i++)
		AtCommResp_data[i]=inp_string[8+i];
	//TODO check for max size
	return true;
}
bool NodeIdInd::ReadNDAnswer(udata_unit8 * NDdata, size_t NDdata_length)
{
	//10 - 64&15 byteadress, data, 8 end of NII without checksumm
	data_length=NDdata_length-18;
	if(NDdata_length<18)
		return false;
	for( size_t i=0;i<2;i++)
		source_adress16[i]=NDdata[0+i];
	for( size_t i=0;i<8;i++)
		sourse_adress64[i]=NDdata[2+i];
	//read data
	for( size_t i=0;i<data_length;i++)
		NIString_data[i]=NDdata[10+i];
	for( size_t i=0;i<2;i++)
		parent_adress16[i]=NDdata[10+data_length+i+0];
	device_type=NDdata[10+data_length+2];
	scource_event=NDdata[10+data_length+3];
	for( size_t i=0;i<2;i++)
		digi_profile_ID[i]=NDdata[10+data_length+i+4];
	for( size_t i=0;i<2;i++)
		manufacturer_ID[i]=NDdata[10+data_length+i+6];
	return true;
}
bool NodeIdInd::ReadString(std::vector<unsigned char> inp_string)
{
	if(inp_string[0]!=XBEE_PACKET_STARTBYTE)
		return false;
	if((unsigned char)inp_string[3]!=(unsigned char)frame_type)
		return false;
	//TODO check checksum?
	//read length
	this->data_length=-30+(inp_string[1]<<8)+inp_string[2];// data=frame-frame_spec+ msb[1]+lsb[0]
	int testgg=inp_string.size();
	if(inp_string.size()<data_length+30+4)
		return false;
	//read frame data
	for( size_t i=0;i<8;i++)
		sourse_adress64[i]=inp_string[4+i];
	for( size_t i=0;i<2;i++)
		source_network_adress16[i]=inp_string[12+i];
	Recieve_Options=inp_string[14];
	for( size_t i=0;i<2;i++)
		source_adress16[i]=inp_string[15+i];
	for( size_t i=0;i<8;i++)
		network_adress64[i]=inp_string[17+i];
	//read data
	for( size_t i=0;i<data_length;i++)
		NIString_data[i]=inp_string[25+i];
	for( size_t i=0;i<2;i++)
		parent_adress16[i]=inp_string[25+data_length+i+0];
	device_type=inp_string[25+data_length+2];
	scource_event=inp_string[25+data_length+3];
	for( size_t i=0;i<2;i++)
		digi_profile_ID[i]=inp_string[25+data_length+i+4];
	for( size_t i=0;i<2;i++)
		manufacturer_ID[i]=inp_string[25+data_length+i+6];
	//TODO check for max size
	return true;
}

std::vector<unsigned char> RemoteATCommandRequest::Sendstr()
{
	unsigned int writable_length=16;// 14 - content size
	std::vector<unsigned char> output(writable_length+4);
	//general info
	output[0]=XBEE_PACKET_STARTBYTE;
	output[1]=(writable_length >> 8) & 0xFF;//length msb
	output[2]=writable_length & 0xFF;//length lsb
	output[3]=frame_type;
	output[4]=frame_ID;
	//dest adress
	for( size_t i=0;i<8;i++)
		output[5+i]=dest_adress64[i];
	for( size_t i=0;i<2;i++)
		output[13+i]=dest_net_adress16[i];
	output[15]=RCOptions;
	for( size_t i=0;i<2;i++)
		output[16+i]=AT_Command[i];
	output[18]=Command_Parameter;
	//get checksumm
	udata_unit8 chksumm=0;
	for( size_t i=0;i<writable_length;i++)
		chksumm+=output[3+i];
	output[writable_length+3]=255-chksumm;
	return output;
}

//Serial_SetChar( SERIAL_0, (size >> 8) & 0xFF ); // send the most significant bit
  //Serial_SetChar( SERIAL_0, size & 0xFF ); // then the LSB